// 引入 createStore
import { createStore } from "vuex";

// 创建 store 仓库
const store = createStore({
  /**
   * 写 状态数据 的地方。
   *    可以简单的理解为  组件的 data 选项
   */
  state() {
    return {
      count: 1,
      msg: "hello vuex",
    };
  },

  /**
   * 存放 getter 的。
   *    getters 可以理解为 组件的 computed 选项
   */
  getters: {
    /**
     * state 就是当前仓库的 state 数据
     * PS: 不能通过 this 去获取 state。必须通过它的第一个参数 state
     */
    plusCount(state, getters, rootState, rootGetters) {
      // state -      当前的 state
      // getters -    当前的 getters
      // rootState -  根模块的 state - 通过它可以获取到别的模块的数据
      // rootGetters -根模块的 getters - 通过它可以获取到别的模块的数据
      console.log("state", state);
      console.log("getters", getters);
      console.log("rootState", rootState);
      console.log("rootGetters", rootGetters);
      return state.count + 1;
    },

    reverseMsg(state) {
      return state.msg.split("").reverse().join("");
    },
  },

  /**
   * 存放 mutation（突变） 的
   *    要去修改 state 的数据，那么唯一遵循规则的方法就是，提交一个突变。
   *    一个 mutation 里面，只能同步的修改 state
   */
  mutations: {
    increment(state, payload) {
      // 同步的修改 state 数据
      console.log("payload", payload);
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
    jianshao(state, payload) {
      // state - 当前的 state 数据
      // payload - 提交这个突变时，传递过来的参数
      console.log("payload", payload);
      state.count -= payload;
    },
  },

  /**
   * 存放 action（动作）的
   *    它与 mutation 的不同之处，就在与 它可以做异步操作。
   *    它不能直接去修改 state。如果异步操作完之后，要修改 state 。可以通过再调用一个 mutation 来实现
   */
  actions: {
    asyncIncrement(context, payload) {
      // context 是一个上下文对象，里面有如下的属性和方法。可以简单的理解为就是 $store
      //    1. state 当前的 state
      //    2. getters 当前的 getters
      //    3. commit() 提交突变的方法
      //    4. dispatch() 派发动作的方法
      //    5. rootState    根仓库的 state
      //    6. rootGetters  根仓库的 getters
      // payload 是派发这个动作（action）时，传递过来的参数
      console.log("context", context);
      console.log("payload", payload);

      // 异步操作
      setTimeout(() => {
        // 让 count++
        // 这里的 context 中虽然可以获取的 state 数据，也可以修改，但是不推荐这样玩。
        // 要修改的话，可以通过 context.commit() 去提交一个对应的 mutation 来修改
        context.commit("increment");
      }, 2000);
    },
    // 对 context 里面要用的东西做解构
    asyncDecrement({ commit }) {
      setTimeout(() => {
        commit("decrement");
      }, 2000);
    },
  },

  /**
   * 存放 module（仓库子模块）的。
   *    项目如果大了之后，state 里面的数据就不好维护了，这时可以使用 modules 将仓库做拆分。
   */
  modules: {},
});

// 导出 store
export default store;
